/**
 * collapsible - jQuery xui
 *
 * Licensed under the GPL:
 *   http://www.gnu.org/licenses/gpl.txt
 *
 * Copyright 2013 xjb [ beymy.en@gmail.com ]
 *
 */
(function($) {

    function wrapPanel(target) {
        var t = $(target);
        var p = t.addClass('collapsible-body').wrap('<div class="collapsible"></div>').parent();
        p.prepend('<div class="collapsible-header">' +
            '<div class="collapsible-icon"></div>' +
            '<div class="collapsible-title"></div>' +
            '</div>');
        p.attr('style', t.attr('style'));
        t.removeAttr('style');
        return p;
    }

    function buildCollapse(target) {
        var state = $(target).data('collapsible');
        var opts = state.options;
        var panel = state.panel;
        var header = panel.children('.collapsible-header');
        var body = panel.children('.collapsible-body');
        var icon = header.children('.collapsible-icon');
        header.find('.collapsible-title').text(opts.title);
        if (body.is(':hidden')) {
            icon.addClass('collapsible-icon-expand');
        } else {
            icon.addClass('collapsible-icon-collapse');
        }
    }

    function collapse(target) {
        var state = $(target).data('collapsible');
        var panel = state.panel;
        var body = panel.children('.collapsible-body');
        var icon = panel.find('>.collapsible-header>.collapsible-icon');
        icon.removeClass('collapsible-icon-collapse').addClass('collapsible-icon-expand');
        body.slideUp(state.options.speed);
    }

    function expand(target) {
        var state = $(target).data('collapsible');
        var panel = state.panel;
        var body = panel.children('.collapsible-body');
        var icon = panel.find('>.collapsible-header>.collapsible-icon');
        icon.removeClass('collapsible-icon-expand').addClass('collapsible-icon-collapse');
        body.slideDown(state.options.speed);
    }

    function bindEvents(target) {
        var state = $(target).data('collapsible');
        var panel = state.panel;
        var header = panel.children('.collapsible-header');
        var body = panel.children('.collapsible-body');

        header.unbind('.collapsible').bind('click.collapsible', function() {
            if (body.is(':hidden')) {
                expand(target);
            } else {
                collapse(target);
            }
        });
    }

    $.fn.collapsible = function(options, param) {
        if (typeof options == 'string') {
            return $.fn.collapsible.methods[options](this, param);
        }
        options = options || {};
        return this.each(function() {
            var opts;
            var state = $.data(this, 'collapsible');
            if (state) {
                opts = $.extend(state.options, options);
            } else {
                opts = $.extend({}, $.fn.collapsible.defaults, $.fn.collapsible.parseOptions(this), options);
                $.data(this, 'collapsible', {
                    options: opts,
                    panel: wrapPanel(this)
                });
                buildCollapse(this);
            }
            bindEvents(this);
        });
    };

    $.fn.collapsible.methods = {
        options: function(jq) {
            return $.data(jq[0], 'collapsible').options;
        },
        collapse: function(jq) {
            return jq.each(function() {
                collapse(this);
            });
        },
        expand: function(jq) {
            return jq.each(function() {
                expand(this);
            });
        }
    };

    $.fn.collapsible.parseOptions = function(target) {
        return $.extend({}, $.parser.parseOptions(target, ['title', {
            'speed': 'number'
        }]));
    };

    $.fn.collapsible.defaults = {
        title: null,
        speed: 200
    };

})(jQuery);
